package tianrun.ziguan.api.calculate.config.service.sync.handler.asset;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;
import tianrun.ziguan.api.calculate.config.dto.request.TAssetUsageAnalysisModuleVO;
import tianrun.ziguan.api.calculate.config.entity.TAssetUsageAnalysisModule;
import tianrun.ziguan.api.calculate.config.entity.TCalAsset;
import tianrun.ziguan.api.calculate.config.entity.TUsageAnalysisModule;
import tianrun.ziguan.api.calculate.config.enums.MoldEnum;
import tianrun.ziguan.api.calculate.config.service.asset.module.ITAssetUsageAnalysisModuleService;
import tianrun.ziguan.api.calculate.config.service.cal.asset.ITCalAssetService;
import tianrun.ziguan.api.calculate.config.service.sync.SyncType;
import tianrun.ziguan.api.calculate.config.service.sync.handler.AbstractSyncHandler;
import tianrun.ziguan.api.calculate.config.service.sync.handler.SyncHandler;
import tianrun.ziguan.api.calculate.config.service.template.analysis.ITUsageAnalysisModuleService;
import tianrun.ziguan.api.calculate.config.utils.CollectionUtil;
import tianrun.ziguan.api.calculate.config.utils.MyBeanUtil;
import tianrun.ziguan.api.calculate.config.utils.Setter;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class AssetUsageAnalysisModuleHandler extends AbstractSyncHandler {

    private final ITCalAssetService calAssetService;
    private final ITUsageAnalysisModuleService usageAnalysisModuleService;
    private final ITAssetUsageAnalysisModuleService assetUsageAnalysisModuleService;

    public AssetUsageAnalysisModuleHandler(ITCalAssetService calAssetService, ITUsageAnalysisModuleService usageAnalysisModuleService, ITAssetUsageAnalysisModuleService assetUsageAnalysisModuleService) {
        this.calAssetService = calAssetService;
        this.usageAnalysisModuleService = usageAnalysisModuleService;
        this.assetUsageAnalysisModuleService = assetUsageAnalysisModuleService;
    }

    @Override
    public MoldEnum mold() {
        return MoldEnum.UsageAnalysis;
    }

    @Override
    public SyncType type() {
        return SyncType.ASSET;
    }

    /**
     * @param moduleIds 同一模板下用量分析组件的id
     * @param parentIds t_template.id or t_cal_asset.id
     */
    @Override
    public void handler(Set<Long> moduleIds, Set<Long> parentIds) {
        Collection<TCalAsset> calAssets = calAssetService.listByIds(parentIds);
        Collection<TUsageAnalysisModule> sources = usageAnalysisModuleService.listByIds(moduleIds);
        Collection<TAssetUsageAnalysisModuleVO> targets = assetUsageAnalysisModuleService.listByCalAssetIds(parentIds);
        Map<Long, TCalAsset> calAssetMap = CollectionUtil.toMap(calAssets, TCalAsset::getId);
        Map<Long, List<TAssetUsageAnalysisModule>> templateTarget = targets.stream().collect(Collectors.groupingBy(TAssetUsageAnalysisModule::getCalAssetId, Collectors.toList()));
        List<TAssetUsageAnalysisModule> list = Lists.newArrayList();
        for (TUsageAnalysisModule source : sources) {
            String sourceCalLabel = source.getCalLabel();
            Long sourceId = source.getId();
            for (Long parentId : parentIds) {
                TCalAsset calAsset = calAssetMap.get(parentId);
                if (calAsset == null) {
                    continue;
                }
                List<TAssetUsageAnalysisModule> _targets = templateTarget.getOrDefault(parentId, Collections.emptyList());
                Map<Long, TAssetUsageAnalysisModule> targetByTemplateModuleIdMap = _targets.stream().filter(v -> Objects.nonNull(v.getTemplateModuleId())).collect(Collectors.toMap(TAssetUsageAnalysisModule::getTemplateModuleId, Function.identity()));
                Map<String, TAssetUsageAnalysisModule> targetByCalLabelMap = _targets.stream().filter(v -> Objects.nonNull(v.getCalLabel())).collect(Collectors.toMap(TAssetUsageAnalysisModule::getCalLabel, Function.identity()));

                TAssetUsageAnalysisModule _target = targetByTemplateModuleIdMap.getOrDefault(sourceId, targetByCalLabelMap.getOrDefault(sourceCalLabel, new TAssetUsageAnalysisModule()));
                list.add(MyBeanUtil.doCopy(source, _target,
                        new Setter<>(_target::setId, _target.getId()),
                        new Setter<>(_target::setTemplateModuleId, source.getId()),
                        new Setter<>(_target::setCalAssetId, parentId)));
            }
        }
        if (list.isEmpty()) return;
        assetUsageAnalysisModuleService.saveOrUpdateBatch(list);
        //删除多余的用量分析
        assetUsageAnalysisModuleService.remove(Wrappers.<TAssetUsageAnalysisModule>lambdaQuery().
                in(TAssetUsageAnalysisModule::getTemplateModuleId, list.stream().map(TAssetUsageAnalysisModule::getTemplateModuleId).collect(Collectors.toList())).
                in(TAssetUsageAnalysisModule::getCalAssetId, parentIds).
                notIn(TAssetUsageAnalysisModule::getId, list.stream().map(TAssetUsageAnalysisModule::getId).collect(Collectors.toList()))
        );
    }

    public void handler_old(Set<Long> moduleIds, Set<Long> parentIds) {
        Collection<TCalAsset> calAssets = calAssetService.listByIds(parentIds);
        Collection<TUsageAnalysisModule> sources = usageAnalysisModuleService.listByIds(moduleIds);
        Collection<TAssetUsageAnalysisModuleVO> targets = assetUsageAnalysisModuleService.listByCalAssetIds(parentIds);
        Map<Long, TCalAsset> calAssetMap = CollectionUtil.toMap(calAssets, TCalAsset::getId);
        Map<Long, Map<String, TAssetUsageAnalysisModule>> templateTarget = targets.stream().collect(Collectors.groupingBy(TAssetUsageAnalysisModule::getCalAssetId, Collectors.toMap(TAssetUsageAnalysisModule::getCalLabel, Function.identity())));
        List<TAssetUsageAnalysisModule> list = Lists.newArrayList();
        for (TUsageAnalysisModule source : sources) {
            String key = source.getCalLabel();
            for (Long parentId : parentIds) {
                TCalAsset calAsset = calAssetMap.get(parentId);
                if (calAsset == null) {
                    continue;
                }
                TAssetUsageAnalysisModule target = new TAssetUsageAnalysisModule();
                Map<String, TAssetUsageAnalysisModule> _targets = templateTarget.getOrDefault(parentId, Collections.emptyMap());
                TAssetUsageAnalysisModule _target = _targets.getOrDefault(key, target);
                list.add(MyBeanUtil.doCopy(source, _target, new Setter<>(_target::setId, null), new Setter<>(_target::setCalAssetId, parentId)));
            }
        }
        if (list.isEmpty()) return;
        assetUsageAnalysisModuleService.saveOrUpdateBatch(list);
    }
}
